package com.fucking.great.context.single.resource;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.fucking.great.context.common.job.TxnContextJob;
import com.fucking.great.context.config.SystemConfigBean;
import com.fucking.great.context.handler.AppRunner;
import com.fucking.great.context.util.SingleUtil;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

import javax.annotation.Resource;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import static org.quartz.CronScheduleBuilder.cronSchedule;

@Resource
public class JobAppRunner implements AppRunner {
    public static final Log logger = LogFactory.get();

    public static final Map<String,Scheduler> JOB_MAP = new ConcurrentHashMap<>();


    public void init(SystemConfigBean systemConfigBean) {

        //创建一个scheduler
        Scheduler scheduler = null;
        String systemName = systemConfigBean.getSystemName();

        if (JOB_MAP.containsKey(systemName)) {
            logger.debug("该systemName[{}],已经存在job任务,不再重复创建.",systemName);
            return;
        }

        try {
            //
            Map<String, String> config = systemConfigBean.getConfig();
            String jobArray = config.get("jobArray");
            if (JSONUtil.isJsonArray(jobArray)) {
                scheduler = StdSchedulerFactory.getDefaultScheduler();
                //
                JSONArray jsonArray = JSONUtil.parseArray(jobArray);
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject jobJson = jsonArray.getJSONObject(i);

                    //
                    try{
                        String cron = jobJson.getStr("cron");
                        String path = jobJson.getStr("path");
                        if(!StrUtil.isAllNotBlank(cron,path)){
                            logger.info("该配置项中没有cron|path,跳过该job");
                            continue;
                        }
                        //创建一个Trigger
                        Trigger trigger = TriggerBuilder.newTrigger()
                                .withSchedule(cronSchedule(cron))
                                .build();
                        //创建一个job
                        JobDetail job = JobBuilder.newJob(TxnContextJob.class)
                                .build();
                        JobDataMap jobDataMap = job.getJobDataMap();
                        jobDataMap.put("path", path);
                        jobDataMap.put("systemName",systemName);
                        //注册trigger和job
                        scheduler.scheduleJob(job,trigger);
                    }catch (Exception e){
                        logger.warn(e,"systemName[{}]中第[{}]个job,注册任务失败",systemName,i);
                    }
                }

                // 启动scheduler
                scheduler.start();
                logger.info("systemName[{}],启动scheduler成功",systemName);
            }else{
                logger.debug("该systemName[{}]没有配置[jobArray]内容或者不符合jsonArray格式,不启用job组件",systemName);
            }
            //
            if (scheduler != null) {
                JOB_MAP.put(systemName,scheduler);
            }
        } catch (SchedulerException e) {
            logger.warn(e,"systemName[{}],启动scheduler失败",systemName);
        }

    }

    @Override
    public void run(SystemConfigBean[] allSystemConfigBean) {
        for (SystemConfigBean systemConfigBean : allSystemConfigBean) {
            this.init(systemConfigBean);
        }
    }

    @Override
    public void destroy() {
        for (Map.Entry<String, Scheduler> schedulerEntry : JOB_MAP.entrySet()) {
            String systemName   = schedulerEntry.getKey();
            Scheduler scheduler = schedulerEntry.getValue();
            if (scheduler != null ) {
                try {
                    scheduler.shutdown();
                } catch (SchedulerException e) {
                    logger.warn(e,"systemName[{}]中第[{}],停止scheduler失败",systemName);
                }
            }
        }
        JOB_MAP.clear();
    }
}
